using System;
using System.Diagnostics;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Project;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.WowAddonStudio.Project;
using IServiceProvider=Microsoft.VisualStudio.OLE.Interop.IServiceProvider;

namespace Microsoft.WowAddonStudio.Tests.Common.Mocks
{
	public class MockProjectNode : ProjectNode
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="MockProjectNode"/> class.
		/// </summary>
		public MockProjectNode()
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="MockProjectNode"/> class.
		/// </summary>
		/// <param name="locator">The locator.</param>
		public MockProjectNode(IDependencyResolver locator)
		{
			SetSite(locator as IServiceProvider);
			ProjectMgr = this;
			SetMembersWithReflection();
		}

		/// <summary>
		/// Sets the members with reflection.
		/// </summary>
		private void SetMembersWithReflection()
		{
			base.ProjectMgr = this;
			//Type type = typeof(ProjectNode);
			//var field =  type.GetField("projectMgr", BindingFlags.NonPublic | BindingFlags.Instance |
			//                            BindingFlags.GetField);
			//field.SetValue(this, this, BindingFlags.NonPublic | BindingFlags.Instance |
			//                            BindingFlags.SetField, null,null);
		}

		/// <summary>
		/// Gets or sets the project MGR.
		/// </summary>
		/// <value>The project MGR.</value>
		public new ProjectNode ProjectMgr { get; set; }


		/// <summary>
		/// Creates new items in a project, adds existing files to a project, or causes Add Item wizards to be run
		/// </summary>
		/// <param name="itemIdLoc"></param>
		/// <param name="op"></param>
		/// <param name="itemName"></param>
		/// <param name="filesToOpen"></param>
		/// <param name="files">Array of file names.
		/// If dwAddItemOperation is VSADDITEMOP_CLONEFILE the first item in the array is the name of the file to clone.
		/// If dwAddItemOperation is VSADDITEMOP_OPENDIRECTORY, the first item in the array is the directory to open.
		/// If dwAddItemOperation is VSADDITEMOP_RUNWIZARD, the first item is the name of the wizard to run,
		/// and the second item is the file name the user supplied (same as itemName).</param>
		/// <param name="dlgOwner"></param>
		/// <param name="editorFlags"></param>
		/// <param name="editorType"></param>
		/// <param name="physicalView"></param>
		/// <param name="logicalView"></param>
		/// <param name="result"></param>
		/// <returns>S_OK if it succeeds</returns>
		/// <remarks>The result array is initalized to failure.</remarks>
		public override int AddItemWithSpecific(uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen,
		                                        string[] files, IntPtr dlgOwner, uint editorFlags, ref Guid editorType,
		                                        string physicalView, ref Guid logicalView, VSADDRESULT[] result)
		{
			editorType = Guid.NewGuid();
			logicalView = Guid.NewGuid();
			result[0] = VSADDRESULT.ADDRESULT_Success;
			FirstChild = SimpleTestServiceLocator.Get<WowFileNode>();
			return VSConstants.S_OK;
		}


		/// <summary>
		/// Loads a project file. Called from the factory CreateProject to load the project.
		/// </summary>
		/// <param name="fileName">File name of the project that will be created.</param>
		/// <param name="location">Location where the project will be created.</param>
		/// <param name="name">If applicable, the name of the template to use when cloning a new project.</param>
		/// <param name="flags">Set of flag values taken from the VSCREATEPROJFLAGS enumeration.</param>
		/// <param name="iidProject">Identifier of the interface that the caller wants returned.</param>
		/// <param name="canceled">An out parameter specifying if the project creation was canceled</param>
		public override void Load(string fileName, string location, string name, uint flags, ref Guid iidProject,
		                          out int canceled)
		{
			try
			{
				base.Load(fileName, location, name, flags, ref iidProject, out canceled);
			}
			catch (Exception e)
			{
				Trace.WriteLine(e);
			}
			canceled = 0;
		}

		/// <summary>
		/// Checks if project is save to load
		/// </summary>
		/// <returns></returns>
		protected override ProjectLoadOption IsProjectSecure()
		{
			return ProjectLoadOption.LoadNormally;
		}

		/// <summary>
		/// Return the value of a project property
		/// </summary>
		/// <param name="propertyName">Name of the property to get</param>
		/// <param name="resetCache">True to avoid using the cache</param>
		/// <returns>
		/// null if property does not exist, otherwise value of the property
		/// </returns>
		public override string GetProjectProperty(string propertyName, bool resetCache)
		{
			string result = null;

			try
			{
				result = base.GetProjectProperty(propertyName, resetCache);
			}
			catch (Exception)
			{
			}

			if (string.IsNullOrEmpty(result))
			{
				if (propertyName == ProjectFileConstants.ProjectGuid)
					result = Guid.NewGuid().ToString();
			}
			return result;
		}


		/// <summary>
		/// This Guid must match the Guid you registered under
		/// HKLM\Software\Microsoft\VisualStudio\%version%\Projects.
		/// Among other things, the Project framework uses this
		/// guid to find your project and item templates.
		/// </summary>
		/// <value></value>
		public override Guid ProjectGuid
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Returns a caption for VSHPROPID_TypeName.
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		public override string ProjectType
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Do the build by invoking msbuild
		/// </summary>
		/// <param name="vsopts"></param>
		/// <param name="config"></param>
		/// <param name="output"></param>
		/// <param name="target"></param>
		/// <returns></returns>
		public override MSBuildResult Build(uint vsopts, string config, IVsOutputWindowPane output, string target)
		{
			Trace.WriteLine(String.Concat("MockProjectNode:Build - Target: ", target));
			return MSBuildResult.Successful;
		}
	}
}